package com.iwhalecloud.bss.kite.cucc.service.shoppingcart.operate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.cart.client.api.cart.operate.IOperateKiteCartAcceptService;
import com.iwhalecloud.bss.kite.cart.client.api.cart.operate.IOperateKiteCartService;
import com.iwhalecloud.bss.kite.cart.client.api.cart.operate.IOperateKiteShoppingCartService;
import com.iwhalecloud.bss.kite.cart.client.api.cart.query.IQueryKiteCartService;
import com.iwhalecloud.bss.kite.cart.client.api.cart.query.IQueryKiteShoppingCartService;
import com.iwhalecloud.bss.kite.cart.client.api.inf.IKiteCartOrderService;
import com.iwhalecloud.bss.kite.cart.client.dto.pos.KitePosDTO;
import com.iwhalecloud.bss.kite.cart.client.dto.req.*;
import com.iwhalecloud.bss.kite.cart.client.dto.req.pos.*;
import com.iwhalecloud.bss.kite.cart.client.dto.rsp.ModifyKiteCartRsp;
import com.iwhalecloud.bss.kite.cart.client.dto.rsp.QryOrderDetailRspDTO;
import com.iwhalecloud.bss.kite.cart.common.constant.KiteCartKeyConsts;
import com.iwhalecloud.bss.kite.cart.common.util.KiteCartObjectUtils;
import com.iwhalecloud.bss.kite.cart.common.util.KiteCartStringUtils;
import com.iwhalecloud.bss.kite.cart.dataservice.cache.KiteCartDcPublicCache;
import com.iwhalecloud.bss.kite.cart.dataservice.entity.ShoppingCartGroupInst;
import com.iwhalecloud.bss.kite.cart.dataservice.mapper.shoppingcart.KiteShoppingCartGroupInstMapper;
import com.iwhalecloud.bss.kite.cart.service.shoppingcart.operate.handler.IBaseOrderInfoPosHandler;
import com.iwhalecloud.bss.kite.client.api.ord.scene.IOrdInstOperService;
import com.iwhalecloud.bss.kite.client.api.shoppingcart.operate.IOperateShoppingCartService;
import com.iwhalecloud.bss.kite.client.api.shoppingcart.operate.IUpdateShoppingCartService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.ord.OrdInstCommDTO;
import com.iwhalecloud.bss.kite.client.dto.shoppingcart.GroupInstAttrExtDTO;
import com.iwhalecloud.bss.kite.client.dto.shoppingcart.ShoppingCartGroupInstAttrDTO;
import com.iwhalecloud.bss.kite.client.dto.shoppingcart.ShoppingCartGroupInstDTO;
import com.iwhalecloud.bss.kite.client.dto.shoppingcart.ShoppingCartItemDTO;
import com.iwhalecloud.bss.kite.common.constant.*;
import com.iwhalecloud.bss.kite.common.util.*;
import com.iwhalecloud.bss.kite.cucc.client.api.goods.IGoodsService;
import com.iwhalecloud.bss.kite.cucc.client.api.order.IOrderService;
import com.iwhalecloud.bss.kite.cucc.client.api.reception.ICustReceptionService;
import com.iwhalecloud.bss.kite.cucc.client.api.scene.ICuccSceneService;
import com.iwhalecloud.bss.kite.cucc.client.api.shoppingcart.operate.ICuccOperateShoppingCartService;
import com.iwhalecloud.bss.kite.cucc.client.dto.cart.*;
import com.iwhalecloud.bss.kite.cucc.client.dto.scene.CuccCustInfoDetailDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.CuccOfferOriginalInfoCache;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.KiteGroupInstAttrExt;
import com.iwhalecloud.bss.kite.dataservice.entity.KiteShoppingCartGroupInst;
import com.iwhalecloud.bss.kite.dataservice.entity.KiteShoppingCartGroupInstAttr;
import com.iwhalecloud.bss.kite.dataservice.mapper.shoppingcart.ShoppingCartGroupInstMapper;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.dto.KiteAttrDTO;
import com.iwhalecloud.bss.kite.manager.dto.KiteChangeDTO;
import com.iwhalecloud.bss.kite.manager.dto.KiteExtSceneInstDTO;
import com.iwhalecloud.bss.kite.manager.dto.KiteSceneInstDTO;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.manager.transaction.KiteTransactional;
import com.iwhalecloud.bss.kite.service.ord.handler.IMarketOrderHandler;
import com.iwhalecloud.bss.kite.service.ord.scene.handler.impl.OrdInstBaseHandler;
import com.iwhalecloud.bss.kite.service.shoppingcart.cache.ShoppingCartGroupCache;
import com.iwhalecloud.bss.kite.service.shoppingcart.util.ShoppingCartUtil;
import com.ztesoft.bss.base.staticdata.CoreDataInteract;
import com.ztesoft.bss.common.bo.OrgInfo;
import com.ztesoft.bss.common.bo.SimpleLoginInfo;
import com.ztesoft.bss.common.exception.BssException;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.bss.rul.core.client.dto.common.RuleCommonParam;
import com.ztesoft.common.logger.api.ZLogger;
import com.ztesoft.common.logger.factory.ZLoggerFactory;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;

@Service
@Transactional(rollbackFor = Exception.class)
public class CuccOperateShoppingCartService implements ICuccOperateShoppingCartService {

    private static final ZLogger LOGGER = ZLoggerFactory
        .getLogger(CuccOperateShoppingCartService.class, KeyConsts.LOG_MODULE);

    @Autowired
    IQuerySceneInstService querySceneInstService;

    @Autowired
    private IOperateShoppingCartService operateShoppingCartService;

    @Autowired
    IOperateSceneInstService operateSceneInstService;

    @Autowired
    IOrdInstOperService ordInstOperService;

    @Autowired
    IOperateShoppingCartService shoppingCartService;

    @Autowired
    private IOrderService orderService;

    @Autowired
    KiteShoppingCartGroupInstMapper kiteShoppingCartGroupInstMapper;

    @Autowired
    private IGoodsService goodsService;

    @Autowired
    private ICuccSceneService cuccSceneService;

    @Override
    public DataResult<Boolean> cacheShoppingCartGroup(SimpleLoginInfo simpleLoginInfo, String sceneInstId,
        String staffId, String custId, String statusCd, String cartId) {
        Assert.hasText(sceneInstId, "sceneInstId must not be empty");
        Assert.hasText(staffId, "staffId must not be empty");
        Assert.hasText(custId, "custId must not be empty");
        Assert.hasText(statusCd, "statusCd must not be empty");
        KiteSceneInstDTO sceneInstDTO = this.querySceneInstService.getSceneInstDTO(sceneInstId);
        //从场景实例中获取购物车分组数据
        ShoppingCartGroupInstDTO groupInstDto = operateShoppingCartService
            .createShoppingCartGroupInstInfo(simpleLoginInfo, sceneInstDTO, statusCd, staffId, custId)
            .getResultObject();
        if (groupInstDto == null) {
            ErrorConsts.SHOPPING_CART_GROUP_NULL_ERROR.throwOut(sceneInstId);
        }

        groupInstDto.setCreateStaff(staffId);
        groupInstDto.setCustId(custId);
        groupInstDto.setCustName(sceneInstDTO.getCustName());
        groupInstDto
            .setCustManagerName(this.querySceneInstService.getCommonAttrValue(sceneInstId, "cust_manager_name"));
        groupInstDto.setOrgId(simpleLoginInfo.getOrgId().toString());
        groupInstDto.setLanId(simpleLoginInfo.getLanId());
        groupInstDto.setStatusCd(statusCd);

        if (KiteStringUtils.isEmpty(groupInstDto.getServiceOfferId())) {
            groupInstDto.setServiceOfferId(sceneInstDTO.getServiceOfferId());
        }

        if (KiteStringUtils.isNotEmpty(cartId) && KiteStringUtils.isEmpty(groupInstDto.getCartId())) {
            groupInstDto.setCartId(cartId);
        }

        //获取购物车属性以及公共属性
        this.packShoppingCartGroupInstAttr(groupInstDto, sceneInstDTO);

        //保存到缓存
        ShoppingCartGroupCache.cacheGroupInstDto(staffId, custId, groupInstDto);
        //获取实例标识和订单项标识键值对
        try {
            Boolean isSavedBefore = false;
            ShoppingCartGroupInst shoppingCartGroupInst = kiteShoppingCartGroupInstMapper
                .listShoppingCartGroupInstByCartId(groupInstDto.getGroupId(), custId, cartId);
            if (!KiteCartObjectUtils.isEmpty(shoppingCartGroupInst)) {
                isSavedBefore = true;
            }

            KiteCartAddRequestDTO request = new KiteCartAddRequestDTO();
            IOperateKiteCartService operateKiteCartService = SpringUtil.getBean(IOperateKiteCartService.class);
            request.setRequest(groupInstDto);
            long time1 = System.currentTimeMillis();

            //保存购物车分组
            operateKiteCartService.saveKiteCart(request);
            long time2 = System.currentTimeMillis();
            LOGGER.info("saveKiteCart total time =========== " + (time2 - time1));

            String lanId = simpleLoginInfo.getLanId();
            String regionId = sceneInstDTO.getRegionId();
            String orgId = simpleLoginInfo.getOrgId().toString();
            OrdInstCommDTO commDto = this
                .getOrdInstCommDto(sceneInstDTO, groupInstDto, sceneInstId, staffId, orgId, lanId, regionId, custId,
                    cartId, isSavedBefore);

            IOrdInstOperService orderInstOperService = SpringUtil.getBean("kiteCartOrdInstOperService");
            orderInstOperService.createOrdInsts(sceneInstDTO, commDto);

            long time3 = System.currentTimeMillis();
            LOGGER.info("createOrdInsts total time =========== " + (time3 - time2));
            LOGGER.info("cacheShoppingCartGroup total time =========== " + (time3 - time1));
        }
        catch (Exception e) {
            LOGGER.error(ErrorConsts.SYSTEM_ERROR.getErrorCode(), e, e.getMessage());
        }
        return ErrorConsts.SUCCESS.getResult(true);
    }

    private OrdInstCommDTO getOrdInstCommDto(KiteSceneInst sceneInst, ShoppingCartGroupInstDTO groupInstDto,
        String groupId, String staffId, String orgId, String lanId, String regionId, String custId, String cartId,
        Boolean isSavedBefore) {
        OrdInstCommDTO commDto = new OrdInstCommDTO();
        commDto.setCartId(cartId);
        commDto.setSceneInstId(groupId);
        commDto.setCreateStaff(staffId);
        commDto.setCreateOrgId(orgId);
        commDto.setUpdateStaff(staffId);
        commDto.setUpdateOrgId(orgId);
        commDto.setVerNum("1.0");
        commDto.setAcceptRegionId(regionId);
        commDto.setAcceptLanId(lanId);
        commDto.setOwnerCustId(custId);
        commDto.setStatusCd(KeyConsts.ORD_INST_STATUS_ORIGINAL);
        commDto.setSavedBefore(isSavedBefore);
        if (Objects.nonNull(sceneInst)) {
            commDto.setCustOrderId(sceneInst.getCustOrderId());
            commDto.setOperType(sceneInst.getOperType());
        }

        List<ShoppingCartItemDTO> cartItemDtos = Objects.isNull(groupInstDto) ?
            Lists.newArrayList() :
            groupInstDto.getShoppingCartItems();
        if (!KiteListUtils.isEmpty(cartItemDtos)) {
            Map<String, String> orderItemRelMap = new HashMap<>();
            for (ShoppingCartItemDTO cartItemDto : cartItemDtos) {
                orderItemRelMap.put(cartItemDto.getObjId(), cartItemDto.getOrderItemId());
            }
            commDto.setOrderItemMap(orderItemRelMap);
        }
        return commDto;
    }

    @Override
    public DataResult<Boolean> clearShoppingCart(String staffId, String custId, RuleCommonParam ruleParam) {
        return null;
    }

    @Override
    public DataResult<String> toSettle(SimpleLoginInfo simpleLoginInfo, String sceneInstId, String custOrderId,
        String staffId, String custId, String statusCd) {

        Assert.hasText(sceneInstId, "sceneInstId must not be empty");
        Assert.hasText(staffId, "staffId must not be empty");
        Assert.hasText(custId, "custId must not be empty");
        //先取购物车分组缓存
        KiteSceneInstDTO sceneInstDTO = this.querySceneInstService.getSceneInstDTO(sceneInstId);
        String cartId = sceneInstDTO.getCartId();
        if (KiteStringUtils.isEmpty(cartId)) {
            IQueryKiteShoppingCartService queryKiteShoppingCartService = SpringUtil
                .getBean(IQueryKiteShoppingCartService.class);
            // 获取分片键 cartId
            cartId = queryKiteShoppingCartService.getShoppingCartIdByEs(staffId).getResultObject().toString();
        }

        IQueryKiteCartService queryKiteCartService = SpringUtil.getBean(IQueryKiteCartService.class);
        KiteCartGetRequestDTO queryRequest = new KiteCartGetRequestDTO();
        queryRequest.setGroupId(sceneInstId);
        queryRequest.setCustId(custId);
        queryRequest.setCartId(cartId);
        queryRequest.setStaffId(staffId);

        ShoppingCartGroupInstDTO cacheGroupInstDto = queryKiteCartService.getShoppingCartGroupInstBaseInfo(queryRequest)
            .getResultObject();
        //从场景实例中获取购物车分组数据
        ShoppingCartGroupInstDTO groupInstDto = operateShoppingCartService
            .createShoppingCartGroupInstInfo(simpleLoginInfo, sceneInstDTO, statusCd, staffId, custId)
            .getResultObject();
        //设置创建时间，场景对象没有创建时间，从第一次缓存的购物车对象中获取创建时间
        groupInstDto.setCreateDate(
            Objects.isNull(cacheGroupInstDto) ? sceneInstDTO.getUpdateDate() : cacheGroupInstDto.getCreateDate());
        //保存购物车分组

        groupInstDto.setCreateStaff(staffId);
        groupInstDto.setCustId(custId);
        groupInstDto.setCustName(sceneInstDTO.getCustName());
        groupInstDto.setCustManagerName(sceneInstDTO.getStaffName());
        groupInstDto.setOrgId(simpleLoginInfo.getOrgId().toString());
        groupInstDto.setLanId(simpleLoginInfo.getLanId());
        groupInstDto.setStatusCd(statusCd);
        groupInstDto.setCartId(cartId);
        groupInstDto.setServiceOfferId(sceneInstDTO.getServiceOfferId());
        //保存公共属性
        this.packShoppingCartGroupInstAttr(groupInstDto, sceneInstDTO);

        String regionId = sceneInstDTO.getRegionId();
        try {
            IOperateKiteCartService operateKiteCartService = SpringUtil.getBean(IOperateKiteCartService.class);
            KiteCartModifyRequestDTO request = new KiteCartModifyRequestDTO();
            request.setRequest(groupInstDto);
            //保存购物车分组
            operateKiteCartService.modifyKiteCart(request).getResultObject();
            //更新缓存
            ShoppingCartGroupCache.cacheGroupInstDto(staffId, custId, groupInstDto);

            String orgId = simpleLoginInfo.getOrgId().toString();
            String lanId = simpleLoginInfo.getLanId().toString();
            OrdInstCommDTO commDto = this
                .getOrdInstCommDto(sceneInstDTO, groupInstDto, sceneInstId, staffId, orgId, lanId, regionId, custId,
                    cartId, Boolean.TRUE);
            IOrdInstOperService orderInstOperService = SpringUtil.getBean("kiteCartOrdInstOperService");
            orderInstOperService.createOrdInsts(sceneInstDTO, commDto);
        }
        catch (Exception e) {
            LOGGER.error(ErrorConsts.SYSTEM_ERROR.getErrorCode(), e, e.getMessage());
        }

        return ErrorConsts.SUCCESS.getResult(cartId.toString());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public DataResult<Boolean> cancelShoppingCartGroup(String staffId, String lanId, String orgId, String regionId,
        String custId, String groupId, String remark) {
        Assert.hasText(staffId, "staffId must not be empty");
        Assert.hasText(custId, "custId must not be empty");
        Assert.hasText(staffId, "staffId must not be empty");
        IQueryKiteShoppingCartService queryKiteShoppingCartService = SpringUtil
            .getBean(IQueryKiteShoppingCartService.class);
        // 获取分片键 cartId
        Long cartId = queryKiteShoppingCartService.getShoppingCartIdByEs(staffId).getResultObject();

        IQueryKiteCartService queryKiteCartService = SpringUtil.getBean(IQueryKiteCartService.class);
        KiteCartGetRequestDTO queryRequest = new KiteCartGetRequestDTO();
        queryRequest.setGroupId(groupId);
        queryRequest.setCustId(custId);
        queryRequest.setCartId(cartId.toString());
        queryRequest.setStaffId(staffId);

        ShoppingCartGroupInstDTO groupInstDto = queryKiteCartService.getKiteCartDetail(queryRequest).getResultObject();
        //
        //        KiteShoppingCartGroupInst groupInst = this.getShoppingCartGroupInst(groupId, custId);
        //        this.checkDeletePriv(staffId, Arrays.asList(groupInst));

        // 2035923 modify by yu.baocheng 如果内存中的场景对象释放掉了，需要重内存加载；
        KiteSceneInst kiteSceneInst = this.querySceneInstService.getSceneInst(groupId, custId);
        //已生成订单不取消
        String custOrderId = kiteSceneInst.getCustOrderId();

        //场景对象回滚
        KiteChangeDTO changeDTO = operateSceneInstService.rollbackSceneInst(groupId, custId);
        //实例数据回滚（撤单订单取消不回滚实例；不是待收费也不需要回滚，过程实例还未入库）
        if (Objects.nonNull(groupInstDto) && !KeyConsts.SERVICE_WITHDRAW.equals(kiteSceneInst.getServiceOfferId())
            && KeyConsts.SHOPPING_CART_GROUP_STATUS_CHARGING.equals(groupInstDto.getStatusCd())) {
            OrdInstCommDTO commDto = operateShoppingCartService
                .getOrdInstCommDto(kiteSceneInst, groupId, staffId, orgId, lanId, regionId, custId);
            ordInstOperService.rollback(changeDTO, commDto);
        }

        //购物车信息归档
        //        if (GeneralSwitchUtils.isSwitchOpened(SwitchConsts.SHOPPING_CART_NEW_ARCHIVE)) {
        //            this.operateShoppingCartGroupInstService.moveToHisNew(Arrays.asList(groupId), staffId, custId, KeyConsts.SHOPPING_CART_GROUP_STATUS_CANCEL,
        //                KeyConsts.SHOPPING_CART_ITEM_STATUS_INVALIDATE, I18nConsts.BSS_KITE_SHOPPING_CART_90001.getMessage());
        //        }
        //        else {
        //            this.operateShoppingCartGroupInstService.moveShoppingCartGroupInfoToHis(Arrays.asList(groupId), staffId, custId,
        //                KeyConsts.SHOPPING_CART_GROUP_STATUS_CANCEL, KeyConsts.SHOPPING_CART_ITEM_STATUS_INVALIDATE, remark);
        //        }

        return ErrorConsts.SUCCESS.getResult(true);
    }

    private void packShoppingCartGroupInstAttr(ShoppingCartGroupInstDTO groupInstDto, KiteSceneInstDTO sceneInstDTO) {
        List<KiteAttr> commonAttrs = sceneInstDTO.getCommonAttrs();
        List<KiteShoppingCartGroupInstAttr> groupInstAttrs = new ArrayList<KiteShoppingCartGroupInstAttr>();
        List<KiteGroupInstAttrExt> groupInstAttrExts = new ArrayList<KiteGroupInstAttrExt>();
        if (!KiteListUtils.isEmpty(commonAttrs)) {
            for (KiteAttr attr : commonAttrs) {
                String attrId = KiteStringUtils.isEmpty(attr.getModuleId()) ?
                    "-1" :
                    attr.getModuleId(); //公共属性还原时直接根据json串还原，这里attrid记录-1，还原的时候区分是场景对象属性还是commonAttr公共属性
                String attrValue = attr.getValue();
                String fieldName = attr.getFieldName();
                ActionType actionType = ActionType.A;
                //如果新旧值不同，则是修改
                if (!StringUtils.isEmpty(attr.getOldValue()) && !StringUtils.isEmpty(attr.getValue()) && !StringUtils
                    .equals(attr.getValue(), attr.getOldValue())) {
                    actionType = ActionType.M;
                }
                //附件较多时入购物车表会超长,这里置空,还原场景时取的是整个对象
                if (KiteStringUtils.isJson(attrValue)) {
                    attrValue = "";
                }
                String operType = ShoppingCartUtil.actionType2OperType(actionType);
                String groupInstAttrId = SnowflakeUtils.generateId().toString();
                KiteShoppingCartGroupInstAttr groupAttr = createShoppingCartGroupInstAttr(groupInstDto, groupInstAttrId,
                    attrId, attrValue, fieldName, operType);
                groupInstAttrs.add(groupAttr);
                //属性串
                KiteGroupInstAttrExt attrExt = new KiteGroupInstAttrExt();
                attrExt.setGroupInstAttrId(groupAttr.getGroupInstAttrId());
                attrExt.setCustId(groupInstDto.getCustId());
                KiteAttr copyAttr = new KiteAttr();
                BeanUtils.copyProperties(attr, copyAttr);
                copyAttr.setAttrValues(null);
                attrExt.setAttrJson(JSON.toJSONString(copyAttr));
                attrExt.setCreateStaff(groupInstDto.getCreateStaff());
                attrExt.setCreateDate(LocalDateTime.now());
                attrExt.setCartId(groupInstDto.getCartId());
                groupInstAttrExts.add(attrExt);
            }
        }

        //获取KiteSceneInst对象的属性
        Map<String, Object> attrDataMap = getKiteSceneInstProperties(groupInstDto, sceneInstDTO);
        List<KiteShoppingCartGroupInstAttr> sceneInstAttrs = (List<KiteShoppingCartGroupInstAttr>) attrDataMap
            .get("attrList");
        List<KiteGroupInstAttrExt> attrExts = (List<KiteGroupInstAttrExt>) attrDataMap.get("attrExtList");
        if (!KiteListUtils.isEmpty(sceneInstAttrs)) {
            groupInstAttrs.addAll(sceneInstAttrs);
        }
        if (!KiteListUtils.isEmpty(attrExts)) {
            groupInstAttrExts.addAll(attrExts);
        }

        // 购物车属性
        List<ShoppingCartGroupInstAttrDTO> groupAttrs = new ArrayList<ShoppingCartGroupInstAttrDTO>();
        List<GroupInstAttrExtDTO> groupAttrExts = new ArrayList<GroupInstAttrExtDTO>();

        if (KiteListUtils.isNotEmpty(groupInstAttrs)) {

            groupInstAttrs.forEach(attr -> {
                ShoppingCartGroupInstAttrDTO groupAttr = new ShoppingCartGroupInstAttrDTO();
                KiteBeanUtils.copyProperties(attr, groupAttr);
                groupAttrs.add(groupAttr);
            });
        }

        if (KiteListUtils.isNotEmpty(groupInstAttrExts)) {

            groupInstAttrExts.forEach(attr -> {
                GroupInstAttrExtDTO groupAttr = new GroupInstAttrExtDTO();
                KiteBeanUtils.copyProperties(attr, groupAttr);
                groupAttrExts.add(groupAttr);
            });
        }

        groupInstDto.setGroupInstAttrs(groupAttrs);
        groupInstDto.setGroupInstAttrExts(groupAttrExts);
    }

    public Map<String, Object> getKiteSceneInstProperties(ShoppingCartGroupInstDTO groupInstDto,
        KiteSceneInstDTO sceneInstDTO) {
        Map<String, Object> attrDataMap = new HashMap<String, Object>();
        List<KiteShoppingCartGroupInstAttr> attrs = new ArrayList<KiteShoppingCartGroupInstAttr>();
        List<KiteGroupInstAttrExt> attrExts = new ArrayList<KiteGroupInstAttrExt>();
        attrDataMap.put("attrList", attrs);
        attrDataMap.put("attrExtList", attrExts);

        KiteExtSceneInstDTO kiteSceneInst = new KiteExtSceneInstDTO();
        KiteBeanUtils.copyProperties(sceneInstDTO, kiteSceneInst);
        java.beans.PropertyDescriptor[] properties = org.springframework.beans.BeanUtils
            .getPropertyDescriptors(kiteSceneInst.getClass());
        for (int i = 0; i < properties.length; i++) {
            java.beans.PropertyDescriptor property = properties[i];
            String fieldName = property.getName();
            Class<?> clazz = property.getPropertyType();
            if (StringUtils.equals(clazz.getName(), "java.lang.Class") || StringUtils.equals("instRelGraph", fieldName)
                || StringUtils.equals("commonAttrs", fieldName)) {
                continue;
            }
            Method readMethod = property.getReadMethod();
            try {
                String valueStr = null;
                Object value = readMethod.invoke(kiteSceneInst);
                if (Objects.isNull(value)) {
                    continue;
                }
                String groupInstAttrId = SnowflakeUtils.generateId().toString();
                if (StringUtils.equals(clazz.getName(), "java.lang.String") || StringUtils
                    .equals(clazz.getName(), "java.lang.Boolean") || StringUtils
                    .equals(clazz.getName(), "java.lang.Long") || StringUtils
                    .equals(clazz.getName(), "java.lang.Integer") || StringUtils
                    .equals(clazz.getName(), "java.lang.Double") || StringUtils
                    .equals(clazz.getName(), "java.time.LocalDateTime")) {
                    valueStr = (String) value;
                }
                else if (StringUtils.equals(clazz.getName(), "java.util.Date")) {
                    valueStr = KiteDateUtils.formatDate((Date) value, KiteDateUtils.DATE_TIME_FORMAT);
                }
                else if (StringUtils.equals(clazz.getName(), "com.iwhalecloud.bss.kite.manager.enums.InstType")) {
                    valueStr = OrdInstBaseHandler.getInstTypeCodeMap().get(((InstType) value).name());
                }
                //attrId设置为-2以便区分是场景对象的属性还是commonAttr公共属性
                attrs.add(createShoppingCartGroupInstAttr(groupInstDto, groupInstAttrId, "-2", valueStr, fieldName,
                    CoreDataInteract.EVT_C_0002_1000));

                String jsonStr = null;
                if ("extParameter".equals(fieldName)) {
                    /*Map<String, Object> extParameterMap = JSONObject.parseObject(JSON.toJSONString(value), Map.class);
                    if (!extParameterMap.containsKey("saveCart")) {
                        extParameterMap.put("saveCart", "saveCart");
                    }*/
                    jsonStr = JSON.toJSONString(value, SerializerFeature.WriteClassName);
                }
                else {
                    jsonStr = JSON.toJSONString(value);
                }
                //属性串
                KiteGroupInstAttrExt attrExt = new KiteGroupInstAttrExt();
                attrExt.setGroupInstAttrId(groupInstAttrId);
                attrExt.setCustId(groupInstDto.getCustId());
                attrExt.setAttrJson(jsonStr);
                attrExt.setCreateStaff(groupInstDto.getCreateStaff());
                attrExt.setCreateDate(LocalDateTime.now());
                attrExts.add(attrExt);
            }
            catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                ErrorConsts.BUSI_COMMON_ERROR.throwOut(e.getMessage());
            }
        }
        return attrDataMap;
    }

    private KiteShoppingCartGroupInstAttr createShoppingCartGroupInstAttr(ShoppingCartGroupInstDTO groupInstDto,
        String groupInstAttrId, String attrId, String attrValue, String fieldName, String operType) {
        KiteShoppingCartGroupInstAttr commonAttr = KiteShoppingCartGroupInstAttr
            .create(KiteShoppingCartGroupInstAttr::new);
        commonAttr.setGroupInstAttrId(groupInstAttrId);
        commonAttr.setGroupId(groupInstDto.getGroupId());
        commonAttr.setCartId(groupInstDto.getCartId());
        commonAttr.setCustId(groupInstDto.getCustId());
        commonAttr.setAttrId(attrId);
        commonAttr.setAttrValue(attrValue);
        commonAttr.setFieldName(fieldName);
        commonAttr.setOperType(operType);
        commonAttr.setCreateStaff(groupInstDto.getCreateStaff());
        commonAttr.setCreateDate(LocalDateTime.now());
        return commonAttr;
    }

    @Override
    public DataResult<Boolean> toCharge(SimpleLoginInfo simpleLoginInfo, String sceneInstId, String custOrderId,
        String staffId, String custId, String statusCd) {
        return null;
    }

    @Override
    public DataResult<Boolean> deleteShoppingCartGroups(CuccKiteCartDeleteRequestDTO request) {

        List<String> groupIds = request.getGroupIds();

        //        if (KiteListUtils.isEmpty(groupIds)) {
        //            ErrorConsts.SHOPPING_CART_GROUP_ID_NULL_ERROR.throwOut(groupIds);
        //        }
        //        List<String> custOrderIds = new ArrayList<>();
        //        for (int i = 0; i < groupIds.size(); i++) {
        //            String groupId = groupIds.get(i);
        //            try {
        ////                KiteSceneInst sceneInst = this.querySceneInstService.getSceneInst(groupId, custId);
        //                this.cancelShoppingCartGroup(staffId, lanId, orgId, sceneInst.getRegionId(), custId, groupId, remark);
        //
        //                custOrderIds.add(sceneInst.getCustOrderId());
        //            }
        //            catch (BssException e) {
        //                // 场景实例不存在的异常不往外抛
        //                if (!ErrorConsts.SCENE_INST_NOT_EXISTS.getCode().equals(e.getFailCode()) && !ErrorConsts.SHOPPING_CART_GROUP_NULL_ERROR.getCode().equals(e.getFailCode())) {
        //                    throw e;
        //                }
        //            }
        //        }
        //        for (int i = 0; i < groupIds.size(); i++) {
        //            String groupId = groupIds.get(i);
        //            logger.debug("Method---deleteShoppingCartGroups  ---------------------------  Resource release start");
        //            // 资源处理,此处对资源处理时单独起事物。不往外抛异常
        //            try {
        //                // 接口受理异常回滚进来时会建立一个标识，如果有此标识，资源释放不单独起事务
        //                if (KiteStringUtils.equals(TraceUtil.getAcceptLogParams(KeyConsts.PREFIX_UNIFIED_INTERFACE + groupId),
        //                    KeyConsts.IFTRUE_T)) {
        //                    resourceManageService.onRemove(groupId, custId);
        //                    TraceUtil.removeTraceParams(KeyConsts.PREFIX_UNIFIED_INTERFACE + groupId);
        //                }
        //                else {
        //                    TransactionUtils.executeNew(() -> {
        //                        resourceManageService.onRemove(groupId, custId);
        //                    });
        //                }
        //                logger.debug("Method---deleteShoppingCartGroups  ---------------------------  Resource release end");
        //            }
        //            catch (BssException e) {
        //                TraceUtil.removeTraceParams(KeyConsts.PREFIX_UNIFIED_INTERFACE + groupId);
        //                logger.error(ErrorConsts.RES_FREE_PREUSE_FAILURE.getErrorCode(), e, e.getMessage());
        //            }
        //        }
        //        //新增集团订单取消事件 本地埋点
        //        DepOrderCancelEvent depOrderCancelEvent = new DepOrderCancelEvent(this, custId, staffId);
        //        depOrderCancelEvent.setCustOrderIds(custOrderIds);
        //        depOrderCancelEvent.setSceneInstIds(groupIds);
        //        applicationContext.publishEvent(depOrderCancelEvent);
        //        // 增加更新crm2dep_custorder_info表逻辑（调用缴费通知后订单生成失败，更新 crm2dep_custorder_info 标识，后面定时任务会根据标识撤单）
        //        if (GeneralSwitchUtils.isSwitchOpened(SwitchConsts.INF_CANCEL_ORDER_SWITCH)) {
        //            KiteSceneInst kiteSceneInst = querySceneInstService.getSceneInst(groupIds.get(0));
        //            if (KiteStringUtils.equals(kiteSceneInst.getAcceptMode(), KeyConsts.ACCEPT_MODE_YYPL)) {
        //                IInfCepOrderService infCancelCepOrder = SpringUtil.getBean(IInfCepOrderService.class);
        //                infCancelCepOrder.updateCrm2depCustorderInfo(custOrderIds, custId);
        //            }
        //        }
        //        if (refund) {
        //            runAfterOrderCancelEvent(custId, staffId, custOrderIds, custOrderIds);
        //        }
        return ErrorConsts.SUCCESS.getResult(true);
    }

    @Override
    public void deleteShoppingCartGroupInfo(String groupId, String custId, String staffId, Boolean deleteGroupInst) {

    }

    @Override
    public void deleteShoppingCartGroupInfo(String groupId, String custId, String staffId) {

    }

    @Override
    public void cancelInvalidGroupInst(String custOrderId, String custId, String staffId, String orgId, String lanId) {

    }

    @Override
    public DataResult<Boolean> archiveShoppingCartData(String groupId, String custId, String staffId, String orgId,
        String remark) {
        String cartId = (String) ContextUtil.getLoginInfo().getUserInfo().getExtParams().get("KITE_SCENEINST_CARTID");
        CompletableFuture.runAsync(() -> {
            IOperateKiteCartService kiteCartService = SpringUtil.getBean(IOperateKiteCartService.class);
            KiteCartCommitRequestDTO request = new KiteCartCommitRequestDTO();
            request.setCartId(cartId);
            request.setGroupIds(Arrays.asList(groupId));
            kiteCartService.commitKiteCart(request);

            KiteSceneInst kiteSceneInst = this.querySceneInstService.getSceneInst(groupId, custId);
            OrdInstCommDTO commDto = getOrdInstCommDto(kiteSceneInst, null, groupId, staffId, orgId,
                kiteSceneInst.getLanId(), kiteSceneInst.getRegionId(), custId, cartId, Boolean.TRUE);
            //迁移实例
            KiteChangeDTO kiteChangeDTO = this.operateSceneInstService.deleteSceneInst(groupId, custId);
            this.ordInstOperService.moveToHis(kiteChangeDTO, commDto, KeyConsts.ORD_INST_STATUS_HISTORY);
        });
        return ErrorConsts.SUCCESS.getResult(Boolean.TRUE);
    }

    @Override
    public DataResult<ShoppingCartGroupInstDTO> createShoppingCartGroupInstInfo(KiteCartRequestDTO request) {

        Map<String, Object> extParams = ContextUtil.getLoginInfo().getUserInfo().getExtParams();
        if (KiteMapUtils.isNotEmpty(extParams) && Objects.isNull(extParams.get("KITE_SCENEINST_CARTID"))) {

            String staffId = request.getStaffId();

            // 获取购物车的分片键，调用ES进行查询，暂时先放在登录信息缓存中,方便场景加载的时候从购物车中获取数据需要通过分片键获取 ，后续改动
            IQueryKiteShoppingCartService queryKiteShoppingCartService = SpringUtil
                .getBean(IQueryKiteShoppingCartService.class);
            // 获取分片键 cartId
            Long cartId = queryKiteShoppingCartService.getShoppingCartIdByEs(staffId).getResultObject();

            if (!KiteObjectUtils.isEmpty(cartId)) {
                extParams.put("KITE_SCENEINST_CARTID", cartId.toString());
            }
        }

        SimpleLoginInfo simpleLoginInfo = ContextUtil.getSimpleLoginInfo();
        String sceneInstId = request.getGroupId();

        try {
            return shoppingCartService
                .createSimpleShoppingCartGroupInstInfo(simpleLoginInfo, sceneInstId, request.getStatusCd(),
                    request.getStaffId(), request.getCustId());
        }
        catch (BssException e) {
            String failCode = e.getFailCode();
            // 场景实例不存在的异常不往外抛，直接返回null
            if (!ErrorConsts.SCENE_INST_NOT_EXISTS.getCode().equals(failCode) && !ErrorConsts.PROD_INST_NOT_EXIST
                .getCode().equals(failCode) && !ErrorConsts.INST_NOT_EXIST.getCode().equals(failCode)) {
                throw e;
            }
            String custId = request.getCustId();
            String lanId = Objects.nonNull(simpleLoginInfo) ? simpleLoginInfo.getLanId().toString() : null;
            String orgId = Objects.nonNull(simpleLoginInfo) ? simpleLoginInfo.getOrgId().toString() : "-1";
            TransactionUtils.executeNew(() -> this
                .cancelShoppingCartGroup(request.getStaffId(), lanId, orgId, null, custId, sceneInstId,
                    I18nConsts.BSS_KITE_SHOPPING_CART_90005.getMessage()));
        }
        return ErrorConsts.EMPTY.getResult(null);
    }

    @Override
    public void archiveOrdInsts(String sceneInstId, String staffId, String orgId, String custId, String cartId) {
        KiteSceneInst kiteSceneInst = this.querySceneInstService.getSceneInst(sceneInstId);
        OrdInstCommDTO commDto = this
            .getOrdInstCommDto(kiteSceneInst, null, sceneInstId, staffId, orgId, kiteSceneInst.getLanId(),
                kiteSceneInst.getRegionId(), custId, cartId, Boolean.TRUE);
        //迁移实例
        KiteChangeDTO kiteChangeDTO = this.operateSceneInstService.deleteSceneInst(sceneInstId, custId);
        this.ordInstOperService.moveToHis(kiteChangeDTO, commDto, KeyConsts.ORD_INST_STATUS_HISTORY);
    }

    @Override
    public DataResult<KiteCartAcceptRspDTO> initCartGroupInstInfo(KiteCartAcceptReqDTO req) {
        CartGroupInstDTO cartGroupInstDTO = new CartGroupInstDTO();

        IOperateKiteCartAcceptService acceptService = SpringUtil.getBean(IOperateKiteCartAcceptService.class);
        KiteCartAcceptRspDTO rspDTO = new KiteCartAcceptRspDTO();

        String serviceOfferId = req.getServiceOfferId();
        String staffId = req.getStaffId();

        // "受理相关基础信息"
        PosBaseInfoDTO posBaseInfo = new PosBaseInfoDTO();

        KiteStaffInfoDTO staffInfo = new KiteStaffInfoDTO();
        Map<String, Object> extParams = ContextUtil.getLoginInfo().getUserInfo().getExtParams();
        String orgId = ContextUtil.getSimpleLoginInfo().getOrgId().toString();
        String provinceId = ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr();
        String lanId ="";
        lanId= ContextUtil.getLoginInfo().getUserInfo().getPostLanId();

        String staffCode = (String) ContextUtil.getLoginInfo().getUserInfo().getExtParams().get("account");
        staffInfo.setCreateOrgId(orgId);
        staffInfo.setCreateStaff(staffId);
        staffInfo.setCreatePost(ContextUtil.getSimpleLoginInfo().getPostId().toString());
        staffInfo.setJkStaffId(KiteMapUtils.getString(extParams, "accountId"));
        staffInfo.setJkStaffName(KiteMapUtils.getString(extParams, "account"));
        KiteBeanUtils.copyProperties(req, posBaseInfo);
        posBaseInfo.setStaffInfo(staffInfo);
        posBaseInfo.setServiceAction("complexService");
        posBaseInfo.setUpdateFlag("add");
        // 订购场景
        if (LocalKeyConsts.BIZTYPE_1001.equals(serviceOfferId) || ServiceOfferConsts.SERVICE_OFFER_ORDER
            .equals(serviceOfferId) || LocalServiceOfferConsts.SERVICE_OFFER_RESOURCE_CHECK.equals(serviceOfferId)) {
            packPosBusiInfo(req, cartGroupInstDTO);

        }
        // 变更场景
        else if (Objects.nonNull(req.getUserInfo()) && KiteStringUtils
            .isNotEmpty(req.getUserInfo().getSerialNumber())) {
            KiteCartUserDTO userInfo = req.getUserInfo();

            //云业务国际针对省级工号特殊处理
            OrgInfo orgInfo=ContextUtil.getLoginInfo().getOrgInfo();
            if(!KiteObjectUtils.isEmpty(orgInfo)&&orgInfo.getOrgLevel()!=null&&orgInfo.getOrgLevel()==10){
                ICustReceptionService custReceptionService = SpringUtil.getBean(ICustReceptionService.class);
                CuccCustInfoDetailDTO cuccCustInfoDTO = custReceptionService.getCustomerInfoNewForNational(req.getCustId());
                if(!KiteStringUtils.isEmpty(cuccCustInfoDTO.getEparchyCode())){
                    lanId= cuccCustInfoDTO.getEparchyCode();
                }
            }
            KitePosDTO kitePosDTO;
            if(KiteCartStringUtils.isEqual("T", KiteCartDcPublicCache.getCodea("20220414001", "init_cart_method_new"))){
                IKiteCartOrderService kiteCartOrderService = SpringUtil.getBean(IKiteCartOrderService.class);
                kitePosDTO = kiteCartOrderService.queryUserInfo(userInfo.getProdId(), req.getCustId(), userInfo.getSerialNumber(), provinceId,
                    lanId, staffCode);
            }else {
                Map<String, Object> orderInfo = orderService
                    .getChangeOriginOrderOld(userInfo.getProdId(), req.getCustId(), userInfo.getSerialNumber(), provinceId,
                        lanId, staffCode,"qryUserDetailInfo_new", "");
                kitePosDTO = JSONObject
                    .toJavaObject(JSON.parseObject(JSON.toJSONString(orderInfo)),
                        com.iwhalecloud.bss.kite.cart.client.dto.pos.KitePosDTO.class);
            }


            IBaseOrderInfoPosHandler orderInfoPosHandler = SpringUtil.getBean(IBaseOrderInfoPosHandler.class);
            QryOrderDetailRspDTO userDetailInfo = orderInfoPosHandler.getOrderInfoPos(kitePosDTO, null, "K", "");
            CartGroupInstDTO cartGroupInst = userDetailInfo.getCartGroupInst();

            if (Objects.nonNull(cartGroupInst)) {
                PosBusiInfoDTO posBusiInfo = cartGroupInst.getPosBusiInfo();
                if (Objects.nonNull(posBusiInfo)) {
                    List<KiteGoodsInfoDTO> goodsInfo = posBusiInfo.getGoodsInfo();
                    // 购物车初始化时传入用户状态
                    String userState = userInfo.getUserState();
                    if (KiteStringUtils.isNotEmpty(userState)) {
                        for (KiteGoodsInfoDTO kiteGoodsInfoDTO : goodsInfo) {
                            KiteUserDTO users = kiteGoodsInfoDTO.getUsers();
                            List<ObjectAttrDTO> attrs = users.getAttrs();
                            if (KiteListUtils.isEmpty(attrs)) {
                                attrs = new ArrayList<ObjectAttrDTO>();
                                users.setAttrs(attrs);
                            }
                            ObjectAttrDTO objectAttrDTO = new ObjectAttrDTO();
                            objectAttrDTO.setAttrCode("userState");
                            objectAttrDTO.setAttrValue(userState);
                            attrs.add(objectAttrDTO);
                        }
                    }
                    if (KiteListUtils.isNotEmpty(goodsInfo)) {
                        for (KiteGoodsInfoDTO kiteGoodsInfoDTO : goodsInfo) {
                            KiteSingleGoodsDTO goods = kiteGoodsInfoDTO.getSingleGoods();
                            if (Objects.nonNull(goods) && KiteStringUtils.isEmpty(goods.getSaleGoodsName())
                                && KiteStringUtils.isNotEmpty(goods.getGoodsSku())) {
                                Map<String, Object> goodsInfoMap = CuccOfferOriginalInfoCache.get(goods.getGoodsSku());
                                List<Map<String, Object>> productCategroys = ( List<Map<String, Object>>)goodsInfoMap.get("productCategroy");
                                packProductCate(productCategroys,posBusiInfo);
                                if (!KiteObjectUtils.isEmpty(goodsInfoMap) && !KiteObjectUtils
                                    .isEmpty(goodsInfoMap.get("goodsName"))) {
                                    goods.setSaleGoodsName(goodsInfoMap.get("goodsName").toString());
                                    goods.setGoodsName(goodsInfoMap.get("goodsName").toString());
                                }
                            }
                            if (KiteStringUtils.isEmpty(goods.getSaleGoodsCode())) {
                                goods.setSaleGoodsCode(goodsService.getPromotionOfferId(goods.getGoodsSku()));
                            }
                        }
                    }
                }
                cartGroupInstDTO.setPosBusiInfo(posBusiInfo);
                cartGroupInstDTO.setOrder(cartGroupInst.getOrder());
            }
        }

        cartGroupInstDTO.setPosBaseInfo(posBaseInfo);

        ModifyKiteCartReq modifyKiteCartReq = new ModifyKiteCartReq();

        modifyKiteCartReq.setCartGroupInst(cartGroupInstDTO);

        // 调用保存购物车接口

        ModifyKiteCartRsp modifyKiteCartRsp = acceptService.modifyKiteCart(modifyKiteCartReq);
        DataResult<KiteCartAcceptRspDTO> result = ErrorConsts.SUCCESS.getResult(null);

        if (Objects.nonNull(modifyKiteCartRsp)) {

            if (Objects.nonNull(modifyKiteCartRsp.getResultObject())) {
                KiteCartAcceptRspDTO acceptRspDTO = new KiteCartAcceptRspDTO();
                KiteBeanUtils.copyProperties(modifyKiteCartRsp.getResultObject(), acceptRspDTO);
                result.setResultObject(acceptRspDTO);
            }
            result.setResultCode(modifyKiteCartRsp.getResultCode());
            result.setResultMsg(modifyKiteCartRsp.getResultMsg());
        }
        return result;
    }


    private void packProductCate(List<Map<String, Object>> productCategroys,PosBusiInfoDTO posBusiInfo ){
        //暂时仅撑单商品
        KiteGoodsInfoDTO kiteGoodsInfoDTO=posBusiInfo.getGoodsInfo().get(0);
        List<KiteProductDTO> productDTOS =kiteGoodsInfoDTO.getSingleGoods().getProducts();
        KiteProductDTO product=productDTOS.stream().filter(productDTO -> KiteStringUtils.equals(productDTO.getProductType(),"base")).findFirst().orElse(null);
        if(product!=null){
            List<ObjectAttrDTO> objectAttrDTOList=product.getAttrs();
            ObjectAttrDTO objectAttrDTO =objectAttrDTOList.stream().filter(attr -> KiteStringUtils.equals(attr.getAttrCode(),"categoryCode")).findFirst().orElse(null);
            for (Map productCategroy : productCategroys) {
                String productType = KiteMapUtils.getString(productCategroy, "productType");
                String categoryId = KiteMapUtils.getString(productCategroy, "categoryId");
                if("base".equals(productType)) {
                    if(objectAttrDTO==null){
                        objectAttrDTO = new ObjectAttrDTO();
                        objectAttrDTO.setAttrCode("categoryCode");
                        objectAttrDTO.setAttrName("产品分类id");
                        objectAttrDTO.setAttrValue(categoryId);
                        objectAttrDTO.setAttrValueDesc("产品分类id");
                        objectAttrDTOList.add(objectAttrDTO);
                    }else{
                        objectAttrDTO.setAttrCode("categoryCode");
                        objectAttrDTO.setAttrName("产品分类id");
                        objectAttrDTO.setAttrValue(categoryId);
                        objectAttrDTO.setAttrValueDesc("产品分类id");
                    }

                }

            }
        }
    }
    private void packPosBusiInfo(KiteCartAcceptReqDTO req, CartGroupInstDTO cartGroupInstDTO) {
        //"受理相关业务信息"
        PosBusiInfoDTO posBusiInfo = new PosBusiInfoDTO();
        List<GoodsInitDetailDTO> singleGoods = req.getSingleGoods();
        List<KiteGoodsInfoDTO> goodsInfos = new ArrayList<KiteGoodsInfoDTO>();
        if (KiteListUtils.isNotEmpty(singleGoods)) {
            singleGoods.forEach(goods -> {
                KiteGoodsInfoDTO goodInfo = new KiteGoodsInfoDTO();
                KiteSingleGoodsDTO single = new KiteSingleGoodsDTO();
                KiteBeanUtils.copyProperties(goods, single);

                if (KiteStringUtils.isEmpty(single.getSaleGoodsName()) && KiteStringUtils
                    .isNotEmpty(goods.getSaleGoodsSku())) {
                    Map<String, Object> goodsInfoMap = CuccOfferOriginalInfoCache.get(goods.getSaleGoodsSku());
                    if (!KiteObjectUtils.isEmpty(goodsInfoMap)) {
                        single.setSaleGoodsName(goodsInfoMap.get("goodsName").toString());
                        /**
                         * 封装基础商品sku和基础商品名称
                         * 从缓存获取基础商品，如果缓存中没有基础商品，则循环销售品下的基础商品
                         */
                        Map<String, Object> baseGoodsInfoMap = CuccOfferOriginalInfoCache.get(goods.getGoodsSku());
                        if( !KiteObjectUtils.isEmpty(baseGoodsInfoMap) ){
                            single.setGoodsSku( baseGoodsInfoMap.get("goodsSku").toString() );
                            single.setGoodsName( baseGoodsInfoMap.get("goodsName").toString() );
                        }else{
                            List<Map<String, Object>> saleGoods = KiteMapUtils.getValue(goodsInfoMap, "saleGoods");
                            for( int i=0;saleGoods!=null&&i<saleGoods.size();i++ ){
                                if( KiteMapUtils.getString(saleGoods.get(i), "goodsSku").equals( goods.getGoodsSku() ) ){
                                    single.setGoodsSku( goodsInfoMap.get("goodsSku").toString() );
                                    single.setGoodsName( goodsInfoMap.get("goodsName").toString() );
                                }
                            }
                        }
                    }
                }
                // 如果GoodsSku为空，或者与SaleGoodsSku相等则重新获取
                if (KiteStringUtils.isEmpty(goods.getGoodsSku())
                    || KiteStringUtils.equals(goods.getGoodsSku(), goods.getSaleGoodsSku())) {
                    Map<String, Object> goodsInfo = CuccOfferOriginalInfoCache.get(goods.getSaleGoodsSku());
                    List<Map<String, Object>> saleGoods = KiteMapUtils.getValue(goodsInfo, "saleGoods");
                    if (KiteListUtils.isNotEmpty(saleGoods)&&saleGoods.size()>0) {
                        String goodsSku = KiteMapUtils.getString(saleGoods.get(0), "goodsSku");
                        goods.setGoodsSku(goodsSku);
                        single.setGoodsSku(goodsSku);
                        /**
                         * 获取基础商品名称
                         */
                        single.setGoodsName( KiteMapUtils.getString(saleGoods.get(0), "goodsName") );
                    }
                }
                if (KiteStringUtils.isEmpty(single.getSaleGoodsCode())) {
                    single.setSaleGoodsCode(goodsService.getPromotionOfferId(goods.getGoodsSku()));
                }
                List<KiteAttrDTO> attrs = Optional.ofNullable(goods.getAttrs()).orElse(new ArrayList<>());
                List<ObjectAttrDTO> goodAttrs = new ArrayList<>();
                attrs.stream().forEach(attr -> {
                    ObjectAttrDTO goodsAttr = new ObjectAttrDTO();
                    goodsAttr.setAttrCode(attr.getFieldName());
                    goodsAttr.setAttrValue(attr.getValue());
                    goodsAttr.setAttrValueDesc(attr.getValueDesc());
                    goodAttrs.add(goodsAttr);
                });
                single.setAttrs(goodAttrs);
                goodInfo.setSingleGoods(single);
                goodsInfos.add(goodInfo);
            });
            posBusiInfo.setGoodsInfo(goodsInfos);
        }

        cartGroupInstDTO.setPosBusiInfo(posBusiInfo);
    }

    /**
     * 一次查询的最大条数(默认)
     */
    private static final int DEFAULT_PAGE_SIZE = 100;

    /**
     * 执行定时任务清理一次的最大条数(默认)
     */
    private static final int DEFAULT_SHOPPING_CART_GROUP_CLEAR_COUNT = 50000;

    /**
     * 一次查询的最大条数
     */
    private int pageSize = DEFAULT_PAGE_SIZE;

    /**
     * 循环查询的最大次数
     */
    private int loopSize = DEFAULT_SHOPPING_CART_GROUP_CLEAR_COUNT / DEFAULT_PAGE_SIZE;

    @Autowired
    IMarketOrderHandler marketOrderHandler;

    @Autowired
    IUpdateShoppingCartService updateShoppingCartService;

    @Override
    public void clearShoppingCart() {
        List<DcPublic> dcPublics = DcPublicCache.get(DcPublicConsts.DC_SHPCART_STYPE_20191018011);
        int count = getCodeaNumberByPkey(dcPublics, DcPublicConsts.DC_SHPCART_GROUP_CACHE_CLEAR_COUNT,
            DEFAULT_SHOPPING_CART_GROUP_CLEAR_COUNT);
        loopSize = count / pageSize + 1;
        String now = DateTimeFormatter.ofPattern(KiteDateUtils.DATE_TIME_FORMAT).format(LocalDateTime.now());
        this.clearInputAndSettle(now);
    }

    /**
     * 根据pkey获取codea并转换成int型
     *
     * @param dcPublics
     * @param pkey
     * @param defaultValue
     * @return
     */
    private int getCodeaNumberByPkey(List<DcPublic> dcPublics, String pkey, int defaultValue) {
        if (CollectionUtils.isEmpty(dcPublics) || StringUtils.isBlank(pkey)) {
            return defaultValue;
        }

        String codea = null;
        for (DcPublic dcPublic : dcPublics) {
            if (Objects.equals(pkey, dcPublic.getPkey())) {
                codea = dcPublic.getCodea();
                codea = StringUtils.isNotBlank(codea) ? codea : null;
                break;
            }
        }

        return NumberUtils.toInt(codea, defaultValue);
    }

    /**
     * 清理待录入和待结算的购物车分组缓存
     */
    private void clearInputAndSettle(String now) {
        List<String> statusCds = new ArrayList<>();
        // 待录入
        statusCds.add(KeyConsts.SHOPPING_CART_GROUP_STATUS_INPUT);
        // 待结算
        statusCds.add(KeyConsts.SHOPPING_CART_GROUP_STATUS_SETTLE);

        ShoppingCartGroupInstMapper shoppingCartGroupInstMapper = SpringUtil.getBean(ShoppingCartGroupInstMapper.class);
        for (int i = 0; i < loopSize; i++) {
            PageHelper.startPage(1, pageSize, false);
            List<KiteShoppingCartGroupInst> groupInsts = TransactionUtils.executeNew(() -> {
                return shoppingCartGroupInstMapper.listDeleteShoppingCartGroupInstsByDay(statusCds, now, 3);
            });
            this.deleteShoppingCart(groupInsts);
            if (CollectionUtils.isEmpty(groupInsts) || groupInsts.size() < pageSize) {
                break;
            }
        }
    }

    /**
     * 删除购物车分组缓存
     *
     * @param groupInsts
     */
    @KiteTransactional(propagation = Propagation.REQUIRES_NEW)
    public void deleteShoppingCart(List<KiteShoppingCartGroupInst> groupInsts) {
        if (CollectionUtils.isEmpty(groupInsts)) {
            return;
        }
        IOperateKiteShoppingCartService operateShoppingCartService = SpringUtil
            .getBean(IOperateKiteShoppingCartService.class);
        groupInsts.stream().forEach(groupInst -> {
            try {
                TransactionUtils.executeNew(() -> {
                    LOGGER.info("购物车group_id>>>>>>>>>>>>>>----------------" + groupInst.getGroupId());
                    List<String> groupIds = Lists.newArrayList(groupInst.getGroupId());
                    KiteCartDeleteRequestDTO dto = new KiteCartDeleteRequestDTO();
                    dto.setGroupIds(groupIds);
                    dto.setCartId(groupInst.getCartId());
                    dto.setCustId(groupInst.getCustId());
                    operateShoppingCartService.deleteKiteCart(dto);
                });
            }
            catch (Exception e) {
                LOGGER.error(ErrorConsts.SYSTEM_ERROR.getErrorCode(), e, "定时任务删除购物车异常：" + e.getMessage());
            }
        });
    }

    @Override
    public DataResult<String> draftKiteCart(DraftKiteCartReqDTO request) {
        request.setStaffId(ContextUtil.getSimpleLoginInfo().getUserId().toString());

        KiteShoppingCartGroupInst queryKiteCartGroupInst = new KiteShoppingCartGroupInst();
        queryKiteCartGroupInst.setCreateStaff(request.getStaffId());
        queryKiteCartGroupInst.setStatusCd(KiteCartKeyConsts.SHOPPING_CART_GROUP_STATUS_DRAFT);

        ShoppingCartGroupInstMapper shoppingCartGroupInstMapper = SpringUtil.getBean(ShoppingCartGroupInstMapper.class);

        Example example = new Example(KiteShoppingCartGroupInst.class);
        example.createCriteria()
            .andEqualTo("createStaff", request.getStaffId())
            .andEqualTo("statusCd", KiteCartKeyConsts.SHOPPING_CART_GROUP_STATUS_DRAFT)
            .andNotEqualTo("groupId", request.getGroupId());
        int count = shoppingCartGroupInstMapper.selectCountByExample(example);
        if (count >= 10) {
            return new DataResult("-1", String.format("每一工号保存草稿最大数量为10条，现已有%s条", String.valueOf(count)), count);
        }


        this.cuccSceneService.getCartIdFromES();

        String sceneInstId = request.getGroupId();
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        if (Objects.isNull(sceneInst)) {
            ErrorConsts.SCENE_INST_NOT_EXISTS.throwOut();
        }


        if (!LocalKeyConsts.ASK_SOURCE_ORDER.equals(sceneInst.getAskSource())) {
            this.toSettle(ContextUtil.getSimpleLoginInfo(), sceneInstId, null,
                    ContextUtil.getSimpleLoginInfo().getUserId().toString(), request.getCustId(), KiteCartKeyConsts.SHOPPING_CART_GROUP_STATUS_DRAFT
                );
        }
        return ErrorConsts.SUCCESS.getResult("");
    }

    @Override
    public String getShoppingCartGroupInstStatusByCartId(String groupId, String custId, String cartId) {
        String status = "";
        ShoppingCartGroupInst shoppingCartGroupInst = kiteShoppingCartGroupInstMapper
            .listShoppingCartGroupInstByCartId(groupId, custId, cartId);
        if (Objects.nonNull(shoppingCartGroupInst)) {
            return  shoppingCartGroupInst.getStatusCd();
        }
        return status;
    }
}
